package filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;

import util.controllerUtils.FrontStyleCodeUtil;
import controllers.displayEntites.LoginDisplay;

public class CheckLoginFilter extends OncePerRequestFilter {
	// filter也是单例的
	private int test = 88;

	@Override
	protected void doFilterInternal(HttpServletRequest request,
			HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		// 不过滤的uri
		String[] notFilter = new String[] { "/images", "/js", "/css",
				"testLogin", "/login/loginPage", "/login/login" ,"webSocket"};
		// 请求的uri
		String uri = request.getRequestURI();
		// 是否过滤
		boolean doFilter = true;
		for (String s : notFilter) {
			if (uri.indexOf(s) != -1) {
				// 如果uri中包含不过滤的uri，则不进行过滤
				doFilter = false;
				break;
			}
		}
		if (doFilter) {
			// 执行过滤
			// 如果是检测登陆者账号二次登陆的则放行如果有二次登录了那么第一个登录者的login已经为null那么检测方法就会在这里直接抛出response.sendError(HttpStatus.UNAUTHORIZED.value()了
			// 做个判断看是否是检测方法的url
			String urlKey = uri;
			urlKey = uri.split("/")[3];
			if (uri.indexOf("/otherAgainLogin/" + urlKey + "/check") != -1) {
				// login都没了无法检查key了直接goOn吧
				// checkLoginKey(request);
				goOn(request, response, filterChain);
			} else {
				// 从session中获取登录者实体
				// Object obj =
				// request.getSession().getAttribute(SessionKeyContent.SESSION_KEY_OBJ_USER_BEAN);
				Object obj = request.getSession().getAttribute("login");
				if (null == obj) {
					boolean isAjaxRequest = isAjaxRequest(request);
					if (isAjaxRequest) {
						response.setCharacterEncoding("UTF-8");
						response.sendError(HttpStatus.UNAUTHORIZED.value(),
								"您已经太长时间没有操作,请刷新页面");
						return;
					}
					// response.sendRedirect("/playViews/test/testLogin");
					response.sendRedirect("/playViews/login/loginPage");
					return;
				} else {
					// 如果session中存在登录者实体，则判断前后端account的id对应的显示实体登录者Display的key是否一致
					if (checkLoginKey(request))
						goOn(request, response, filterChain);
					else
						response.sendRedirect("http://localhost:8080/playViews/login/loginPage");
				}
			}
		} else {
			// 如果不执行过滤则是登录界面或者静态资源的访问不管，则继续
			// 如果请求的是登陆页面session存在登陆者login则自动跳到首页
			// if (uri.indexOf("/loginPage") != -1) {
			// // 如果uri中包含不过滤的uri，则不进行过滤
			//
			// }
			goOn(request, response, filterChain);
		}
	}

	/**
	 * 判断是否为Ajax请求 <功能详细描述>
	 * 
	 * @param request
	 * @return 是true, 否false
	 * @see [类、类#方法、类#成员]
	 */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		String header = request.getHeader("X-Requested-With");
		if (header != null && "XMLHttpRequest".equals(header))
			return true;
		else
			return false;
	}

	private void goOn(HttpServletRequest request, HttpServletResponse response,
			FilterChain filterChain) throws IOException, ServletException {

		FrontStyleCodeUtil fs = FrontStyleCodeUtil
				.getFrontStyleCodeUtilEntity();
		String frontStyle = FrontStyleCodeUtil.quoteStyle(
				fs.getBootstrap_min_css(), fs.getBootstrap_min_js(),
				fs.getBootstrap_theme_min_css(), fs.getJquery_min_js());
		// model.addAttribute("FrontStyle",
		// FrontStyleCodeUtil.quoteStyle(fs.getBootstrap_min_css(),fs.getBootstrap_theme_min_css(),fs.getBootstrap_min_js()));
		// String var=
		// FrontStyleCodeUtil.quoteStyle(fs.getDateTimePicker_Bootstrap_bootstrap_datetimepicker_fr_js(),
		// fs.getDateTimePicker_Bootstrap_bootstrap_datetimepicker_js(),
		// fs.getDateTimePicker_Bootstrap_bootstrap_datetimepicker_min_css(),
		// fs.getDateTimePicker_Bootstrap_bootstrap_min_css(), fs
		// .getJquery_min_js(), fs
		// .getBootstrap_datetimepicker_zh_CN_js());

		request.setAttribute("FrontStyle", frontStyle);
		// 登录成功加入轮询是否二次登录情况super.vm页面
		// response.getOutputStream().print("#parse('super.vm')");
		// request.setAttribute("exeParam",
		// "<script>exeParam();function exeParam(){alert(\"exeParam\");document.write(\"#parse('super.vm')\")}</script>");
		//
		//
		// response.getWriter().close();
		filterChain.doFilter(request, response);
	}

	// 登录成功后请求其他页面时检测前后key是否正確吧去掉key==session的login的id吧因爲如果是在多個頁面的話一個頁面提交了請求其他頁面的request屬性沒變就不能=sessionlogin的id值了
	public boolean checkLoginKey(HttpServletRequest request) {
		HttpSession hs = request.getSession();
		LoginDisplay login = (LoginDisplay) hs.getAttribute("login");
		if (login == null)
			return false;
		// 使用result风格的获取url路径得到指定的值getAttribute("key");getParameter("key");无法获得路径上声明的{key}根本不算属性名怎么获得
		// 拆分路径
		String urlKey = request.getRequestURI();
		String urlParams[] = urlKey.split("/");
		urlKey = urlParams[3];
		// System.out.println("没设置前的login属性：" + login.getEncryptionId());
		if (urlKey != null) {
			try {
				if (Long.parseLong(urlKey) == login.getEncryptionId()) {
					// 需要测试下不调用该方法对应的login对象改变值是否有传递 结果是有的对象存于内存中属性变则相应引用该对象都一样
					// 不需要重新设置login
					// Object loginObj2 = hs.getAttribute("login");
					// LoginDisplay login2 = (LoginDisplay) loginObj2;
					// System.out
					// .println("session不重新setAttribute并通过session再次获得login的属性值为"
					// + login2.getEncryptionId());
					return true;
				}
			} catch (Exception e) {
				// 出现key NumberFormatException异常则返回到登录页面

			}
		}
		return false;
	}
}
